/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.toolkit.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import who.tmap.bo.Annotations;
import who.tmap.bo.cd.CDColorPattern;
import who.tmap.bo.cd.CartographicDisplay;
import who.tmap.bo.cd.ColorPatternClassification;

public class AnnotationsHelper {

	public static final String COLOR_PATTERN_LOW_RANGE ="low";
	public static final String COLOR_PATTERN_HIGH_RANGE ="high";	
	// Used as a legend entry, when displaying a legend based on a Non-Numeric classification
	public static final String COLOR_PATTERN_NON_NUMERIC ="val";
	
	public static final String DEFAULT_ENTRY ="${" + COLOR_PATTERN_LOW_RANGE + "} to ${" + COLOR_PATTERN_HIGH_RANGE + "}";	
	// The default Non-Numeric legend entry pattern used to display Non-Numeric data
	public static final String NON_NUMERIC_ENTRY ="${" + COLOR_PATTERN_NON_NUMERIC +"}";

    public String replaceAnnotations( Map<String, Object> context, String str ) {
    	
    	for( String fieldName : context.keySet() ) {
    		String field ="${" + fieldName.toUpperCase() + "}";
    		Object obj =context.get( fieldName );
    		String value = obj != null ? obj.toString() : "";
    		
    		int pos =-1;
    		do {
    			pos =str.toUpperCase().indexOf( field );
    			if ( pos != -1 ) {
    				str =str.substring( 0, pos ) + value + str.substring( pos + field.length() );
    			}
    		} while ( pos != -1 );
    	}
    	
    	return str;
    }	
    
    /**
     * This method is used when user swaps from a numeric based classification to a non-numeric based one 
     * @param ann: The collection of annotations
     * @param currentSelectedClassification: The current classification in use, such as NON_NUMERIC (see ColorPatternClassification class)
     */
    public void updateLegend( Annotations ann, Integer currentSelectedClassification ) {
    	List<String> oldLegend = ann.getColorPatternLegend();
    	List<String> newLegend = new ArrayList<String>();
    	
    	String legendStr = currentSelectedClassification == ColorPatternClassification.NON_NUMERIC ? NON_NUMERIC_ENTRY : DEFAULT_ENTRY;
    	
    	for ( String line : oldLegend ) {
    		newLegend.add( legendStr );
    	}
    	
    	ann.setColorPatternLegend(newLegend);
    }
    
    /**
     * This method apply ranges to legend depending on the current classification: 
     * <UL>
     * <LI> For a Non-Numeric based one, the legend pattern being used is AnnotationHelper.CAPTION_ENTRY
     * <LI> For a Numeric based one, the legend pattern being used is AnnotationHelper.DEFAULT_ENTRY
     * </UL>
     * @param nbRanges: The ranges count used to populate the legend
     * @param ann: The annotations that must be set as an entry inside the legend
     * @param cd: The CartographicDisplay used to retrieve the current classification in use
     */
	public void applyRanges( int nbRanges, Annotations ann, int classification ) {
		List<String> legend =ann.getColorPatternLegend();
		Boolean usingCaption =null;
		
		usingCaption =classification == ColorPatternClassification.NON_NUMERIC;
		
		if ( legend == null ) {
			legend =new ArrayList<String>();
			ann.setColorPatternLegend( legend );
		}
		
		if ( nbRanges < legend.size() ) {
			
			for( int ct =nbRanges; ct < legend.size(); ct++ ) {
				legend.remove( ct );
			}
			
		} else if ( nbRanges > legend.size() ) {
			
			for( int ct =legend.size(); ct < nbRanges; ct++ ) {
				
				if ( usingCaption ) {
					legend.add( ct, new String( AnnotationsHelper.NON_NUMERIC_ENTRY ) );
				} else {
					legend.add( ct, new String( AnnotationsHelper.DEFAULT_ENTRY ) );
				}
				
			}
		}

	}
	
	/**
	 * This method is used when the user click on the reset range button, displayed 
	 * @param legends: The legend to modify
	 * @param cd: The CartographicDisplay, used to retrieve the current classification
	 */
	public void resetRanges( List<String> legends, CartographicDisplay cd ) {
		legends.clear();
		
		for( int ct =0; ct < legends.size(); ct++ ) {
			if ( ((CDColorPattern)cd).getClassification() == ColorPatternClassification.NON_NUMERIC ) {
				legends.add( new String( AnnotationsHelper.NON_NUMERIC_ENTRY ));
			} else {
				legends.add( new String( AnnotationsHelper.DEFAULT_ENTRY ) );
			}
		}
	}    
	
}
